package com.xh3140.android.widget.dialog;

import android.content.Context;
import android.text.Editable;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.Size;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.xh3140.android.widget.dialog.callback.ConfigParamsCallback;
import com.xh3140.android.widget.dialog.callback.ConfigViewCallback;
import com.xh3140.android.widget.dialog.params.BaseParams;
import com.xh3140.android.widget.dialog.params.DialogParams;
import com.xh3140.android.widget.dialog.params.InputParams;
import com.xh3140.android.widget.dialog.view.FooterView;
import com.xh3140.android.widget.dialog.view.HeaderView;
import com.xh3140.android.widget.dialog.view.InputView;
import com.xh3140.android.widget.dialog.view.RootView;

/**
 * 输入对话框
 */
@SuppressWarnings("unused")
public final class InputDialog extends BaseDialog<InputView> {
    /**
     * 输入对话框属性
     */
    private final Params mParams;

    /**
     * 输入对话框属性数据类
     */
    private static final class Params {
        public final DialogParams dialog;
        public final BaseParams<InputDialog> base;
        public final InputParams input;

        private Params(@NonNull DialogParams dialog, @NonNull BaseParams<InputDialog> base, @NonNull InputParams input) {
            this.dialog = dialog;
            this.base = base;
            this.input = input;
        }
    }

    private InputDialog(@NonNull Params params) {
        super(params.dialog);
        mParams = params;
    }

    @NonNull
    @Override
    protected RootView<InputView> initRootView(@NonNull Context context) {
        final InputDialog dialog = this;
        return new RootView<InputView>(context) {
            @Override
            protected HeaderView initHeaderView(@NonNull Context context) {
                return new HeaderView(context, mParams.base.header);
            }

            @Override
            protected InputView initBodyView(@NonNull Context context) {
                return new InputView(context, mParams.input);
            }

            @Override
            protected FooterView initFooterView(@NonNull Context context) {
                return new FooterView(context, dialog, mParams.base.footer);
            }
        };
    }

    @Override
    public void onStart() {
        super.onStart();
        // 是否弹出输入法
        if (mParams.input.showSoft) {
            showSoftInput();
        }
    }

    /**
     * 获取输入框文本
     */
    @Nullable
    public Editable getInputText() {
        return requireRootView().requireBodyView().getText();
    }

    /**
     * 输入对话框构建器
     * 设置输入对话框属性
     */
    public static final class Builder extends BaseDialog.Builder<InputDialog, Builder> {
        /**
         * 对话框输入主体视图配置属性
         */
        private final InputParams mInputParams;

        public Builder(@NonNull Context context, @IntRange(from = 0) int buttonCount) {
            super(context, buttonCount);
            mInputParams = new InputParams(context);
            mDialogParams.showDividers = -1;
        }

        public Builder(@NonNull FragmentActivity activity, @IntRange(from = 0) int buttonCount) {
            super(activity, buttonCount);
            mInputParams = new InputParams(mDialogParams.context);
            mDialogParams.showDividers = -1;
        }

        public Builder(@NonNull Fragment fragment, @IntRange(from = 0) int buttonCount) {
            super(fragment, buttonCount);
            mInputParams = new InputParams(mDialogParams.context);
            mDialogParams.showDividers = -1;
        }

        /**
         * 构建对话框
         * 这个方法应该在所有配置结束后调用
         */
        @Override
        public InputDialog build() {
            return new InputDialog(new Params(mDialogParams, mBaseParams, mInputParams));
        }

        /**
         * 配置输入主体视图属性
         *
         * @param callback 配置回调
         */
        public Builder configInputParams(@NonNull ConfigParamsCallback<InputParams> callback) {
            callback.callback(mInputParams);
            return this;
        }

        /**
         * 设置输入主体视图输入类型
         *
         * @param type 输入类型
         */
        public Builder setInputType(int type) {
            mInputParams.inputType = type;
            return this;
        }

        /**
         * 设置输入主体视图文本
         *
         * @param text 文本
         */
        public Builder setInputText(@Nullable CharSequence text) {
            mInputParams.text = text;
            return this;
        }

        /**
         * 设置输入主体视图文本字体大小 sp
         *
         * @param textSize 字体大小
         */
        public Builder setInputTextSize(float textSize) {
            mInputParams.textSize = textSize;
            return this;
        }

        /**
         * 设置输入主体视图文本字体颜色 argb
         *
         * @param textColor 字体颜色
         */
        public Builder setInputTextColor(@ColorInt int textColor) {
            mInputParams.textColor = textColor;
            return this;
        }

        /**
         * 设置输入主体视图文本字体样式
         *
         * @param typeface 字体样式
         */
        public Builder setInputTypeface(int typeface) {
            mInputParams.typeface = typeface;
            return this;
        }

        /**
         * 设置输入主体视图提示语文本
         *
         * @param text 提示语文本
         */
        public Builder setInputHint(@Nullable CharSequence text) {
            mInputParams.hint = text;
            return this;
        }

        /**
         * 设置输入主体视图提示语文本颜色
         *
         * @param textColor 文本颜色
         */
        public Builder setInputHintColor(@ColorInt int textColor) {
            mInputParams.hintColor = textColor;
            return this;
        }

        /**
         * 设置输入主体视图文本位置
         *
         * @param gravity 位置
         */
        public Builder setInputGravity(int gravity) {
            mInputParams.gravity = gravity;
            return this;
        }

        /**
         * 设置输入主体视图是否单行
         *
         * @param isSingle 标志
         */
        public Builder setInputSingleLine(boolean isSingle) {
            mInputParams.isSingleLine = isSingle;
            return this;
        }

        /**
         * 设置输入主体视图最大行数
         *
         * @param maxLines 最大行数
         */
        public Builder setInputMaxLines(int maxLines) {
            mInputParams.maxLines = maxLines;
            return this;
        }

        /**
         * 设置输入主体视图每行最大显示长度
         *
         * @param maxEms 最大显示长度
         */
        public Builder setInputMaxEms(int maxEms) {
            mInputParams.maxEms = maxEms;
            return this;
        }

        /**
         * 设置输入主体视图最大输入长度
         *
         * @param maxLength 最大输入长度
         */
        public Builder setInputMaxLength(int maxLength) {
            mInputParams.maxLength = maxLength;
            return this;
        }

        /**
         * 设置输入主体视图边框线条粗细 px
         *
         * @param width 边框线条粗细
         */
        public Builder setInputStrokeWidth(@Px int width) {
            mInputParams.strokeWidth = width;
            return this;
        }

        /**
         * 设置输入主体视图边框线条颜色 argb
         *
         * @param color 边框线条颜色
         */
        public Builder setInputStrokeColor(@ColorInt int color) {
            mInputParams.strokeColor = color;
            return this;
        }

        /**
         * 设置输入主体视图圆角半径 px
         *
         * @param radius 圆角半径
         */
        public Builder setInputRadius(@Px int radius) {
            mInputParams.radius = radius;
            return this;
        }

        /**
         * 设置输入主体视图背景颜色 argb
         *
         * @param backgroundColor 背景颜色
         */
        public Builder setInputBackgroundColor(@ColorInt int backgroundColor) {
            mInputParams.backgroundColor = backgroundColor;
            return this;
        }

        /**
         * 设置输入主体视图资源ID
         *
         * @param resId 资源ID
         */
        public Builder setInputBackgroundResourceId(@DrawableRes int resId) {
            mInputParams.backgroundResource = resId;
            return this;
        }

        /**
         * 设置输入主体视图显示时是否弹出输入法
         *
         * @param showSoft 标识
         */
        public Builder setInputShowSoft(boolean showSoft) {
            mInputParams.showSoft = showSoft;
            return this;
        }

        /**
         * 设置输入视图内边距
         * 格式：[start, top, end, bottom] px
         *
         * @param padding 边距
         */
        public Builder setInputPadding(@Nullable @Size(4) int[] padding) {
            mInputParams.padding = padding;
            return this;
        }

        /**
         * 设置输入视图内边距
         *
         * @param padding 边距 px
         */
        public Builder setInputPadding(@Px int padding) {
            mInputParams.padding = new int[]{padding, padding, padding, padding};
            return this;
        }

        /**
         * 设置输入视图内边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public Builder setInputPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mInputParams.padding = new int[]{left, top, right, bottom};
            return this;
        }

        /**
         * 设置输入视图外边距
         * 格式：[start, top, end, bottom] px
         *
         * @param margins 边距
         */
        public Builder setInputMargins(@Nullable @Size(4) int[] margins) {
            mInputParams.margins = margins;
            return this;
        }

        /**
         * 设置输入视图外边距
         *
         * @param margins 边距 px
         */
        public Builder setInputMargins(@Px int margins) {
            mInputParams.margins = new int[]{margins, margins, margins, margins};
            return this;
        }

        /**
         * 设置输入视图外边距
         *
         * @param left   左边距 px
         * @param top    上边距 px
         * @param right  右边距 px
         * @param bottom 下边距 px
         */
        public Builder setInputMargins(@Px int left, @Px int top, @Px int right, @Px int bottom) {
            mInputParams.margins = new int[]{left, top, right, bottom};
            return this;
        }

        /**
         * 设置输入主体视图高度 px
         *
         * @param height 高度
         */
        public Builder setInputHeight(@Px int height) {
            mInputParams.height = height;
            return this;
        }

        /**
         * 设置输入主体视图配置回调
         * 拥有绝对控制权的回调，它在其他属性配置结束后回调
         * 一般情况不要使用它，除非提供的现有配置属性不满足需求
         *
         * @param callback 配置回调
         */
        public Builder setInputViewCallback(@Nullable ConfigViewCallback<InputView> callback) {
            mInputParams.callback = callback;
            return this;
        }
    }
}
